package com.sky.java_nio;

import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.junit.Test;

/**
 * 
 *@Description: http://ifeve.com/channels/
 *@Author:hjt 
 *@Version:1.0.0
 */
public class NIO_Channel {

	/**
	 *  一、Java NIO的通道类似流，但又有些不同：
		既可以从通道中读取数据，又可以写数据到通道。但流的读写通常是单向的。
		通道可以异步地读写。
		通道中的数据总是要先读到一个Buffer，或者总是要从一个Buffer中写入
		
		从通道读取数据到缓冲区，从缓冲区写入数据到通道：
		Channel -> Buffer
		Buffer -> Channel
		
		二、Channel的实现
		FileChannel 从文件中读写数据。
		DatagramChannel 能通过UDP读写网络中的数据。
		SocketChannel 能通过TCP读写网络中的数据。
		ServerSocketChannel可以监听新进来的TCP连接，像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。
	 */
	
	private int capacity = 48;
	
	
	/****************  使用FileChannel读取数据到Buffer *******************************/
	@Test
	public void testReadData () throws Exception {
		RandomAccessFile aFile = new RandomAccessFile("D:\\test\\data.txt", "rw");
		FileChannel fileChannel = aFile.getChannel();
		
		//创建指定容量的buffer
		ByteBuffer dst = ByteBuffer.allocate(capacity);
		//读取信息到缓存buffer中
		int bytesRead = fileChannel.read(dst);
		while (bytesRead != -1){
			System.out.println("read:" + bytesRead);
			
			//切换buffer为待读
			dst.flip();
			
			while (dst.hasRemaining()){
				//一次读取 1 byte
				System.out.println(dst.get());
			}
			
			//切换buffer为待写状态
			dst.clear();
			bytesRead = fileChannel.read(dst);
		}
		
		aFile.close();
	}
	
}
